1   /*
2    * Copyright (C) 2012 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect.testing.google;
18  
19  import static com.google.common.collect.testing.features.CollectionSize.ZERO;
20  import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
21  import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEY_QUERIES;
22  import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
23  import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUE_QUERIES;
24  import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
25  import static com.google.common.truth.Truth.assertThat;
26  
27  import com.google.common.annotations.GwtCompatible;
28  import com.google.common.collect.ImmutableList;
29  import com.google.common.collect.Multimap;
30  import com.google.common.collect.testing.Helpers;
31  import com.google.common.collect.testing.features.CollectionSize;
32  import com.google.common.collect.testing.features.MapFeature;
33  
34  import java.util.Collection;
35  import java.util.Iterator;
36  import java.util.List;
37  import java.util.Map.Entry;
38  
39  /**
40   * Tests for {@link Multimap#remove(Object, Object)}.
41   *
42   * @author Louis Wasserman
43   */
44  @GwtCompatible
45  public class MultimapRemoveEntryTester<K, V> extends AbstractMultimapTester<K, V, Multimap<K, V>> {
46    @MapFeature.Require(SUPPORTS_REMOVE)
47    public void testRemoveAbsent() {
48      assertFalse(multimap().remove(sampleKeys().e0, sampleValues().e1));
49      expectUnchanged();
50    }
51  
52    @CollectionSize.Require(absent = ZERO)
53    @MapFeature.Require(SUPPORTS_REMOVE)
54    public void testRemovePresent() {
55      assertTrue(multimap().remove(sampleKeys().e0, sampleValues().e0));
56  
57      assertFalse(multimap().containsEntry(sampleKeys().e0, sampleValues().e0));
58      expectMissing(samples.e0);
59      assertEquals(getNumElements() - 1, multimap().size());
60      assertGet(sampleKeys().e0, ImmutableList.<V>of());
61    }
62  
63    @CollectionSize.Require(absent = ZERO)
64    @MapFeature.Require({ SUPPORTS_REMOVE, ALLOWS_NULL_KEYS })
65    public void testRemoveNullKeyPresent() {
66      initMultimapWithNullKey();
67  
68      assertTrue(multimap().remove(null, getValueForNullKey()));
69  
70      expectMissing(Helpers.mapEntry((K) null, getValueForNullKey()));
71      assertGet(getKeyForNullValue(), ImmutableList.<V>of());
72    }
73  
74    @CollectionSize.Require(absent = ZERO)
75    @MapFeature.Require({ SUPPORTS_REMOVE, ALLOWS_NULL_VALUES })
76    public void testRemoveNullValuePresent() {
77      initMultimapWithNullValue();
78  
79      assertTrue(multimap().remove(getKeyForNullValue(), null));
80  
81      expectMissing(Helpers.mapEntry(getKeyForNullValue(), (V) null));
82      assertGet(getKeyForNullValue(), ImmutableList.<V>of());
83    }
84  
85    @MapFeature.Require({ SUPPORTS_REMOVE, ALLOWS_NULL_KEY_QUERIES})
86    public void testRemoveNullKeyAbsent() {
87      assertFalse(multimap().remove(null, sampleValues().e0));
88      expectUnchanged();
89    }
90  
91    @MapFeature.Require({ SUPPORTS_REMOVE, ALLOWS_NULL_VALUE_QUERIES})
92    public void testRemoveNullValueAbsent() {
93      assertFalse(multimap().remove(sampleKeys().e0, null));
94      expectUnchanged();
95    }
96  
97    @MapFeature.Require(value = SUPPORTS_REMOVE, absent = ALLOWS_NULL_VALUE_QUERIES)
98    public void testRemoveNullValueForbidden() {
99      try {
100       multimap().remove(sampleKeys().e0, null);
101       fail("Expected NullPointerException");
102     } catch (NullPointerException expected) {
103       // success
104     }
105     expectUnchanged();
106   }
107 
108   @MapFeature.Require(value = SUPPORTS_REMOVE, absent = ALLOWS_NULL_KEY_QUERIES)
109   public void testRemoveNullKeyForbidden() {
110     try {
111       multimap().remove(null, sampleValues().e0);
112       fail("Expected NullPointerException");
113     } catch (NullPointerException expected) {
114       // success
115     }
116     expectUnchanged();
117   }
118 
119   @MapFeature.Require(SUPPORTS_REMOVE)
120   @CollectionSize.Require(absent = ZERO)
121   public void testRemovePropagatesToGet() {
122     List<Entry<K, V>> entries = Helpers.copyToList(multimap().entries());
123     for (Entry<K, V> entry : entries) {
124       resetContainer();
125 
126       K key = entry.getKey();
127       V value = entry.getValue();
128       Collection<V> collection = multimap().get(key);
129       assertNotNull(collection);
130       Collection<V> expectedCollection = Helpers.copyToList(collection);
131 
132       multimap().remove(key, value);
133       expectedCollection.remove(value);
134 
135       assertThat(collection).has().exactlyAs(expectedCollection);
136       assertEquals(!expectedCollection.isEmpty(), multimap().containsKey(key));
137     }
138   }
139 
140   @MapFeature.Require(SUPPORTS_REMOVE)
141   @CollectionSize.Require(absent = ZERO)
142   public void testRemovePropagatesToAsMap() {
143     List<Entry<K, V>> entries = Helpers.copyToList(multimap().entries());
144     for (Entry<K, V> entry : entries) {
145       resetContainer();
146 
147       K key = entry.getKey();
148       V value = entry.getValue();
149       Collection<V> collection = multimap().asMap().get(key);
150       assertNotNull(collection);
151       Collection<V> expectedCollection = Helpers.copyToList(collection);
152 
153       multimap().remove(key, value);
154       expectedCollection.remove(value);
155 
156       assertThat(collection).has().exactlyAs(expectedCollection);
157       assertEquals(!expectedCollection.isEmpty(), multimap().containsKey(key));
158     }
159   }
160 
161   @MapFeature.Require(SUPPORTS_REMOVE)
162   @CollectionSize.Require(absent = ZERO)
163   public void testRemovePropagatesToAsMapEntrySet() {
164     List<Entry<K, V>> entries = Helpers.copyToList(multimap().entries());
165     for (Entry<K, V> entry : entries) {
166       resetContainer();
167 
168       K key = entry.getKey();
169       V value = entry.getValue();
170 
171       Iterator<Entry<K, Collection<V>>> asMapItr = multimap().asMap().entrySet().iterator();
172       Collection<V> collection = null;
173       while (asMapItr.hasNext()) {
174         Entry<K, Collection<V>> asMapEntry = asMapItr.next();
175         if (key.equals(asMapEntry.getKey())) {
176           collection = asMapEntry.getValue();
177           break;
178         }
179       }
180       assertNotNull(collection);
181       Collection<V> expectedCollection = Helpers.copyToList(collection);
182 
183       multimap().remove(key, value);
184       expectedCollection.remove(value);
185 
186       assertThat(collection).has().exactlyAs(expectedCollection);
187       assertEquals(!expectedCollection.isEmpty(), multimap().containsKey(key));
188     }
189   }
190 }